home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 001-025 / disk_023 / ver30 / gnusymbol.c < prev    next >
C/C++ Source or Header  |  1992-05-06  |  18KB  |  550 lines

  1. /*
  2.  * Name:    MicroEMACS
  3.  *        Symbol table stuff for GNU emacs compatability
  4.  * Version:    29
  5.  * Last edit:    19-Apr-86
  6.  * By:        {sun, amdahl, cbosgd}!rtech!gonzo!daveb
  7.  *
  8.  * Symbol tables, and keymap setup.
  9.  * The terminal specific parts of building the
  10.  * keymap has been moved to a better place.
  11.  *
  12.  * This version matches the standard GNU Emacs 17.49 bindings.
  13.  * With this file, MicroEMACS is a proper subset of GNU.
  14.  *
  15.  * If a GNU feature was misnamed, it was moved.
  16.  * If a GNU feature was "nearly" right, it was noted for later work.
  17.  * If a MicroEMACS feature was incompatible, it was dropped.
  18.  *
  19.  * Compatibility NOW for the future!
  20.  */
  21. #include    "def.h"
  22.  
  23. #define    DIRLIST    0            /* Disarmed!            */
  24.  
  25. # define    DEL    0x7f
  26. # define    ESC    0x1b
  27.  
  28. /* # define DAVEB    *//* Dave Brower specials, not GNU compatibility */
  29.  
  30. /*
  31.  * Defined by "main.c".
  32.  */
  33. extern    int    ctrlg();        /* Abort out of things        */
  34. extern    int    quit();            /* Rude Quit            */
  35. extern    int    ctlxlp();        /* Begin macro            */
  36. extern    int    ctlxrp();        /* End macro            */
  37. extern    int    ctlxe();        /* Execute macro        */
  38. extern  int    showversion();        /* Show version numbers, etc.    */
  39.  
  40. /*
  41.  * defined by "gnucmds.c"
  42.  */
  43. extern    int    savebuffs();        /* GNU style save-some-buffers    */
  44. extern    int    savequit();        /* GNU save-buffers-kill-emacs    */
  45. extern    int    suspend();        /* GNU style suspend        */
  46. extern    int    notmodified();        /* GNU make buffer undirty    */
  47. extern    int    scrollother();        /* GNU scroll other window    */
  48.  
  49. /*
  50.  * Defined by "search.c".
  51.  */
  52. extern    int    forwsearch();        /* Search forward        */
  53. extern    int    backsearch();        /* Search backwards        */
  54. extern  int    searchagain();        /* Repeat last search command    */
  55. extern  int    forwisearch();        /* Incremental search forward    */
  56. extern  int    backisearch();        /* Incremental search backwards    */
  57. extern  int    queryrepl();        /* Query replace        */
  58.  
  59. /*
  60.  * Defined by "basic.c".
  61.  */
  62. extern    int    gotobol();        /* Move to start of line    */
  63. extern    int    backchar();        /* Move backward by characters    */
  64. extern    int    gotoeol();        /* Move to end of line        */
  65. extern    int    forwchar();        /* Move forward by characters    */
  66. extern    int    gotobob();        /* Move to start of buffer    */
  67. extern    int    gotoeob();        /* Move to end of buffer    */
  68. extern    int    forwline();        /* Move forward by lines    */
  69. extern    int    backline();        /* Move backward by lines    */
  70. extern    int    forwpage();        /* Move forward by pages    */
  71. extern    int    backpage();        /* Move backward by pages    */
  72. extern    int    setmark();        /* Set mark            */
  73. extern    int    swapmark();        /* Swap "." and mark        */
  74. extern    int    gotoline();        /* Go to a specified line.    */
  75.  
  76. /*
  77.  * Defined by "buffer.c".
  78.  */
  79. extern    int    listbuffers();        /* Display list of buffers    */
  80. extern    int    usebuffer();        /* Switch a window to a buffer    */
  81. extern    int    killbuffer();        /* Make a buffer go away.    */
  82.  
  83. #if    DIRLIST
  84. /*
  85.  * Defined by "dirlist.c".
  86.  */
  87. extern    int    dirlist();        /* Directory list.        */
  88. #endif
  89.  
  90. /*
  91.  * Defined by "file.c".
  92.  */
  93. extern    int    fileread();        /* Get a file, read only    */
  94. extern    int    filevisit();        /* Get a file, read write    */
  95. extern    int    filewrite();        /* Write a file            */
  96. extern    int    filesave();        /* Save current file        */
  97. extern    int    filename();        /* Adjust file name        */
  98.  
  99. /*
  100.  * Defined by "random.c".
  101.  */
  102. extern    int    selfinsert();        /* Insert character        */
  103. extern    int    showcpos();        /* Show the cursor position    */
  104. extern    int    twiddle();        /* Twiddle characters        */
  105. extern    int    quote();        /* Insert literal        */
  106. extern    int    openline();        /* Open up a blank line        */
  107. extern    int    newline();        /* Insert CR-LF            */
  108. extern    int    deblank();        /* Delete blank lines        */
  109. extern    int    indent();        /* Insert CR-LF, then indent    */
  110. extern    int    forwdel();        /* Forward delete        */
  111. extern    int    backdel();        /* Backward delete        */
  112. extern    int    killline();        /* Kill forward            */
  113. extern    int    yank();            /* Yank back from killbuffer.    */
  114.  
  115. /*
  116.  * Defined by "region.c".
  117.  */
  118. extern    int    killregion();        /* Kill region.            */
  119. extern    int    copyregion();        /* Copy region to kill buffer.    */
  120. extern    int    lowerregion();        /* Lower case region.        */
  121. extern    int    upperregion();        /* Upper case region.        */
  122.  
  123. /*
  124.  * Defined by "spawn.c".
  125.  */
  126. extern    int    spawncli();        /* Run CLI in a subjob.        */
  127.  
  128. /*
  129.  * Defined by "window.c".
  130.  */
  131. extern    int    reposition();        /* Reposition window        */
  132. extern    int    refresh();        /* Refresh the screen        */
  133. extern    int    nextwind();        /* Move to the next window    */
  134. extern  int    prevwind();        /* Move to the previous window    */
  135. extern    int    mvdnwind();        /* Move window down        */
  136. extern    int    mvupwind();        /* Move window up        */
  137. extern    int    onlywind();        /* Make current window only one    */
  138. extern    int    splitwind();        /* Split current window        */
  139. extern    int    enlargewind();        /* Enlarge display window.    */
  140. extern    int    shrinkwind();        /* Shrink window.        */
  141.  
  142. /*
  143.  * Defined by "word.c".
  144.  */
  145. extern    int    backword();        /* Backup by words        */
  146. extern    int    forwword();        /* Advance by words        */
  147. extern    int    upperword();        /* Upper case word.        */
  148. extern    int    lowerword();        /* Lower case word.        */
  149. extern    int    capword();        /* Initial capitalize word.    */
  150. extern    int    delfword();        /* Delete forward word.        */
  151. extern    int    delbword();        /* Delete backward word.    */
  152.  
  153. /*
  154.  * Defined by "extend.c".
  155.  */
  156. extern    int    extend();        /* Extended commands.        */
  157. extern    int    help();            /* Help key.            */
  158. extern    int    bindtokey();        /* Modify key bindings.        */
  159. extern    int    wallchart();        /* Make wall chart.        */
  160.  
  161. typedef    struct    {
  162.     short    k_key;            /* Key to bind.            */
  163.     int    (*k_funcp)();        /* Function.            */
  164.     char    *k_name;        /* Function name string.    */
  165. }    KEY;
  166.  
  167. /*
  168.  * Default key binding table. This contains
  169.  * the function names, the symbol table name, and (possibly)
  170.  * a key binding for the builtin functions. There are no
  171.  * bindings for C-U or C-X. These are done with special
  172.  * code, but should be done normally.
  173.  */
  174.  
  175. /* GNU standard bindings that are missing are commented out with the
  176.  * following notations:
  177.  *
  178.  *    /*B    Braindamaged in current implementation.
  179.  *    /*D    Design restructuring is needed.
  180.  *    /*E    Easy, a few hours.
  181.  *    /*H    Hard, (days) but possible if desirable.
  182.  *    /*I    Impossible (weeks), much too hard to do right.
  183.  *    /*M    Moderate difficulty, a day or so.
  184.  *    /*T    On the to do list.
  185.  *    /*U    Undecided.
  186.  *    /*X    Means unnecessary to do.
  187.  *    /*W    Current version is wrong.
  188.  *
  189.  *   Well, braindamaged is a bit too strong, but doing all the argument
  190.  *   processing in the main loop, and not having meta- ancd ctrl-x
  191.  *   be bindable commands seems kinda funny to me (daveb).
  192.  */
  193.  
  194. KEY    key[] = {
  195.     KCTRL|'@',    setmark,    "set-mark-command",
  196.     KCTRL|'A',    gotobol,    "beginning-of-line",
  197.     KCTRL|'B',    backchar,    "backward-char",
  198. /*DHX    KCTRL|'C',    ???,        "mode-specific-command-prefix",    */
  199.     KCTRL|'D',    forwdel,    "delete-char",
  200.     KCTRL|'E',    gotoeol,    "end-of-line",
  201.     KCTRL|'F',    forwchar,    "forward-char",
  202.     KCTRL|'G',    ctrlg,        "keyboard-quit",
  203.     KCTRL|'H',    help,        "help-command",
  204. /*DHX    KCTRL|'I',    ???,        "indent-for-tab-command",    */
  205.     KCTRL|'J',    indent,        "newline-and-indent",
  206.     KCTRL|'K',    killline,    "kill-line",
  207.     KCTRL|'L',    refresh,    "recenter",
  208.             /*W actually doesn't recenter...        */
  209.  
  210.     KCTRL|'M',    newline,    "newline",
  211.     KCTRL|'N',    forwline,    "next-line",
  212.     KCTRL|'O',    openline,    "open-line",
  213.     KCTRL|'P',    backline,    "previous-line",
  214.     KCTRL|'Q',    quote,        "quoted-insert",
  215.     KCTRL|'R',    backisearch,    "isearch-backward",
  216.     KCTRL|'S',    forwisearch,    "isearch-forward",
  217.     KCTRL|'T',    twiddle,    "transpose-characters",
  218. /*BMT    KCTRL|'U',    ???,        "universal-argument,"        */
  219.     KCTRL|'V',    forwpage,    "scroll-up",
  220.     KCTRL|'W',    killregion,    "kill-region",
  221. /*BMT    KCTRL|'X',    ???,        "Control-X-prefix",        */
  222.     KCTRL|'Y',    yank,        "yank",
  223.             /*WET doesn't set point! */
  224.  
  225.     KCTRL|'Z',    suspend,    "suspend-emacs",
  226.  
  227. /*BMT    KMETA,        ???,        "ESC-prefix",            */
  228. /*DX    KCTRL|']',    ???,        "abort-recursive-edit",        */
  229. /*DIX    KCTRL|'_',    ???,        "undo",                */
  230.  
  231.     DEL,        backdel,    "delete-backward-char",
  232.  
  233. /*DIX    KCTLX|KCTRL|'A',???,        "add-mode-abbrev",        */
  234.     KCTLX|KCTRL|'B',listbuffers,    "list-buffers",
  235.     KCTLX|KCTRL|'C',savequit,    "save-buffers-kill-emacs",
  236.  
  237. #if    DIRLIST
  238.     KCTLX|KCTRL|'D',dirlist,    "list-directory",
  239. #endif
  240.  
  241. /*DIX    KCTLX|KCTRL|'E',???,        "eval-last-sexp",        */
  242.     KCTLX|KCTRL|'F',filevisit,    "find-file",
  243. /*DIX    KCTLX|KCTRL|'H',???,        "inverse-add-mode=abbrev",    */
  244. /*MT    KCTLX|KCTRL|'I',???,        "indent-rigidly",        */
  245.     KCTLX|KCTRL|'L',lowerregion,    "downcase-region",
  246. /*ET    KCTLX|KCTRL|'N', ???,        "set-goal-column"        */
  247.     KCTLX|KCTRL|'O',deblank,    "delete-blank-lines",
  248. /*MU    KCTLX|KCTRL|'P',???,        "mark-page"             */
  249.      KCTLX|KCTRL|'R',fileread,    "file-file-read-only",
  250.                 /*WU incorrect behaviour...        */
  251.     KCTLX|KCTRL|'S',filesave,    "file-buffer",
  252.  
  253. /*EU    KCTLX|KCTRL|'T',???,        "transpose-lines",        */
  254.     KCTLX|KCTRL|'U',upperregion,    "upcase-region",
  255. /*EU    KCTLX|KCTRL|'V',findalternate,    "find-alternate-file",        */
  256.     KCTLX|KCTRL|'W',filewrite,    "write-file",
  257.     KCTLX|KCTRL|'X',swapmark,    "exchange-point-and-mark",
  258.     KCTLX|KCTRL|'Z',spawncli,    "suspend-emacs",
  259.  
  260. /*MT    KCTLX|ESC    ???,        "repeat-complex-command",    */
  261. /*U    KCTLX|'$'    ???,        "set-selective-display",    */
  262.     KCTLX|'(',    ctlxlp,        "start-kbd-macro",
  263.     KCTLX|')',    ctlxrp,        "end-kbd-macro",
  264. /*DIX    KCTLX|'+',    ???,        "add-global-abbrev",        */
  265. /*DIX    KCTLX|'-',    ???,        "inverse-add-global-abbrev",    */
  266. /*MX    KCTLX|'.',    ???,        "set-fill-prefix",        */
  267. /*HX    KCTLX|'/',    ???,        "point-to-register",        */
  268. /*MT    KCTLX|'0',    ???,        "delete-window",        */
  269.     KCTLX|'1',    onlywind,    "delete-other-windows",
  270.     KCTLX|'2',    splitwind,    "split-window-vertically",
  271. /*MX    KCTLX|'4',    ???,        "ctl-x-4-prefix",        */
  272. /*DHX    KCTLX|'5',    ???,        "split-window-horizontally",    */
  273. /*EX    KCTLX|';',    ???,        "set-comment-column",        */
  274. /*HU    KCTLX|'<',    ???,        "scroll-left",            */
  275.     KCTLX|'=',    showcpos,    "what-cursor-position",
  276. /*HU    KCTLX|'>',    ???,        "scroll-right",            */
  277. /*MU    KCTLX|'[',    ???,        "backward-page",        */
  278. /*MU    KCTLX|']',    ???,        "forward-page",            */
  279.     KCTLX|'^',    enlargewind,    "enlarge-window",
  280. /*HX    KCTLX|'`',    ???,        "next-error",            */
  281. /*MU    KCTLX|'A',    ???,        "append-to-buffer",        */
  282.     KCTLX|'B',    usebuffer,    "switch-to-buffer",
  283. /*MX    KCTLX|'D',    ???,        "dired",            */
  284.     KCTLX|'E',    ctlxe,        "call-last-kbd-macro",
  285. /*EU    KCTLX|'F',    ctlxe,        "set-fill-column",        */
  286. /*HX    KCTLX|'G',    ???,        "insert-register",        */
  287. /*EU    KCTLX|'H',    ???,        "mark-whole-buffer",        */
  288. /*MU    KCTLX|'I',    ???,        "insert-file",            */
  289. /*HX    KCTLX|'J',    ???,        "register-to-point",        */
  290.     KCTLX|'K',    killbuffer,    "kill-buffer",
  291. /*MU    KCTLX|'L',    ???,        "count-lines-page",        */
  292. /*HU    KCTLX|'N',    ???,        "narrow-to-region",        */
  293.     KCTLX|'O',    nextwind,    "other-window",
  294. /*HU    KCTLX|'P',    ???,        "narrow-to-page",        */
  295. /*MX    KCTLX|'Q',    ???,        "kbd-macro-qry",        */
  296. /*HX    KCTLX|'R',    ???,        "copy-rectangle-to-register",    */
  297.     KCTLX|'S',    savebuffs,    "save-some-buffers",
  298. /*HX    KCTLX|'U',    ???,        "advertised-undo",        */
  299. /*HX    KCTLX|'W',    ???,        "widen",            */
  300. /*HX    KCTLX|'{',    ???,        "shrink-window-horizontally",    */
  301. /*HX    KCTLX|'}',    ???,        "enlarge-window-horizontally",    */
  302. /*MT    KCTLX|DEL,    ???,        "backward-kill-sentence,"    */
  303.  
  304. /*MU    KMETA|KCTRL|'@',???,        "mark-sexp",            */
  305. /*MU    KMETA|KCTRL|'A',???,        "beginning-of-defun",        */
  306. /*MU    KMETA|KCTRL|'B',???,        "backwards-sexp",        */
  307. /*MX    KMETA|KCTRL|'C',???,        "exit-recursive-edit",        */
  308. /*MU    KMETA|KCTRL|'D',???,        "down-list",            */
  309. /*MU    KMETA|KCTRL|'E',???,        "end-of-defun",            */
  310. /*MU    KMETA|KCTRL|'F',???,        "forward-sexp",            */
  311. /*MU    KMETA|KCTRL|'H',???,        "mark-defun",            */
  312. /*MU    KMETA|KCTRL|'J',???,        "indent-new-comment-line",    */
  313. /*MU    KMETA|KCTRL|'K',???,        "kill-sexp",            */
  314. /*MU    KMETA|KCTRL|'N',???,        "foward-list",            */
  315. /*EU    KMETA|KCTRL|'O',???,        "split-line",            */
  316. /*MU    KMETA|KCTRL|'P',???,        "backward-list",        */
  317. /*HX    KMETA|KCTRL|'S',???,        "isearch-forward-regexp",    */
  318. /*MU    KMETA|KCTRL|'T',???,        "transpose-sexps",        */
  319. /*MU    KMETA|KCTRL|'U',???,        "backward-up-list",        */
  320.     KMETA|KCTRL|'V',scrollother,    "scroll-other-window",
  321. /*ET    KMETA|KCTRL|'W',???,        "append-next-kill",        */
  322.  
  323. /*IX    KMETA|ESC,    ???        "eval-expression",        */
  324. /*IX    KMETA|CTRL|'\',    ???        "indent-region",        */
  325. /*MU    KMETA|' ',    ???        "just-one-space",        */
  326. /*HT    KMETA|'!',    ???,        "shell-command", */
  327. /*HU    KMETA|'$',    ???,        "spell-word", */
  328.     KMETA|'%',    queryrepl,    "query-replace",
  329. /*IX    KMETA|'\'',    ???,        "abbrev-prefix-mark",        */
  330. /*TU    KMETA|'(',    ???,        "insert-parenthesis", */
  331. /*HU    KMETA|')',    ???,        "move-past-close-and-reindent", */
  332. /*HX    KMETA|',',    ???,        "tags-loop-continue",        */
  333. /*DT    KMETA|'-',    ???,        "negative-argument",        */
  334.     KMETA|'>',    gotoeob,    "end-of-buffer",
  335. /*MU    KMETA|'=',    ???,        "count-lines-region",        */
  336.     KMETA|'<',    gotobob,    "beginning-of-buffer",
  337. /*TT    KMETA|'@',    ???,        "mark-word",            */
  338. /*MU    KMETA|'[',    ???,        "backward-paragraph",        */
  339. /*TT    KMETA|'\\',    ???,        "delete-horizontal-space",    */
  340. /*MU    KMETA|']',    ???,        "forward-paragraph",        */
  341. /*TT    KMETA|'^',    ???,        "delete-indentation",        */
  342. /*MU    KMETA|'A',    ???,        "backward-sentence",        */
  343.     KMETA|'B',    backword,    "backward-word",
  344.     KMETA|'C',    capword,    "capitalize-word",
  345.     KMETA|'D',    delfword,    "kill-word",
  346. /*MU    KMETA|'E',    ???,        "forward-sentence",        */
  347.     KMETA|'F',    forwword,    "forward-word",
  348. /*HT    KMETA|'G',    ???,        "fill-region",            */
  349. /*MU    KMETA|'H',    ???,        "mark-paragraph",        */
  350. /*DMX    KMETA|'I',    ???,        "tab-to-tab-stop",        */
  351. /*MU    KMETA|'J',    ???,        "indent-new-comment-line",    */
  352.     KMETA|'L',    lowerword,    "downcase-word",
  353. /*EU    KMETA|'M',    ???,        "back-to-indentation",        */
  354. /*HT    KMETA|'Q',    ???,        "fill-paragraph",        */
  355.     KMETA|'R',    reposition,    "move-to-window-line",
  356. /*ET    KMETA|'T',    ???,        "transpose-words",        */
  357.     KMETA|'U',    upperword,    "upcase-word",
  358.     KMETA|'V',    backpage,    "scroll-down",
  359.     KMETA|'W',    copyregion,    "copy-region-as-kill",
  360.     KMETA|'X',    extend,        "execute-extended-command",
  361. /*HDX    KMETA|'Y',    ???,        "yank-pop",            */
  362. /*MU    KMETA|'Z',    ???,        "zap-to-char",            */
  363. /*HT    KMETA|'|',    ???,        "shell-command-on-region",    */
  364.     KMETA|'~',    notmodified,    "not-modified",
  365.     KMETA|DEL,    delbword,    "backward-kill-word",
  366.  
  367.     /*
  368.     ** These are unbound functions, callable by name.
  369.     ** They are GNU compatible (to various degrees).
  370.     */
  371.  
  372.  
  373. /*    -1,        ???,        "append-next-kill",    */
  374. /*    -1,        ???,        "apropos",        */
  375.     -1,        wallchart,    "describe-bindings",
  376. /*MT    -1,        ???,        "digit-argument",    */
  377.     -1,        showversion,    "emacs-version",
  378.     -1,        bindtokey,    "global-set-key",
  379.     -1,        gotoline,    "goto-line",
  380.     -1,        quit,        "kill-emacs",
  381.     -1,        backsearch,    "search-backward",
  382.     -1,        forwsearch,    "search-forward",
  383.     -1,        selfinsert,    "self-insert-command",
  384.     -1,        filename,    "set-visited-file-name",
  385.  
  386.     /* These are duplicate names for GNU compatible functions,
  387.     ** or incompatible commands I've left lying around for now.
  388.     ** The old command names get used as args to keydup() in the
  389.     ** various tty/xxx/ttykbd.c modules for function keys.
  390.     */
  391.  
  392.     -1,        backchar,    "back-char",
  393.     -1,        backline,    "back-line",
  394.     -1,        backpage,    "back-page",
  395.     -1,        prevwind,    "back-window",    
  396.     -1,        mvdnwind,    "down-window",
  397.     -1,        enlargewind,    "enlarge-window",
  398.     -1,        ctlxe,        "execute-macro",
  399.     -1,        forwchar,    "forw-char",
  400.     -1,        forwline,    "forw-line",
  401.     -1,        forwpage,    "forw-page",
  402.     -1,        nextwind,    "forw-window",
  403.     -1,        help,        "help",
  404.     -1,        selfinsert,    "ins-self",
  405.     -1,        killregion,    "kill-region",
  406.     -1,        searchagain,    "search-again",
  407.     -1,        setmark,    "set-mark",
  408.     -1,        shrinkwind,    "shrink-window",
  409.     -1,        mvupwind,    "up-window",
  410.             /*MT incorrect behaviour */
  411.  
  412. };
  413.  
  414. #define    NKEY    (sizeof(key) / sizeof(key[0]))
  415.  
  416. /*
  417.  * Symbol table lookup.
  418.  * Return a pointer to the SYMBOL node, or NULL if
  419.  * the symbol is not found.
  420.  */
  421. SYMBOL    *
  422. symlookup(cp)
  423. register char    *cp;
  424. {
  425.     register SYMBOL    *sp;
  426.  
  427.     sp = symbol[symhash(cp)];
  428.     while (sp != NULL) {
  429.         if (strcmp(cp, sp->s_name) == 0)
  430.             return (sp);
  431.         sp = sp->s_symp;
  432.     }
  433.     return (NULL);
  434. }
  435.  
  436. /*
  437.  * Take a string, and compute the symbol table
  438.  * bucket number. This is done by adding all of the characters
  439.  * together, and taking the sum mod NSHASH. The string probably
  440.  * should not contain any GR characters; if it does the "*cp"
  441.  * may get a nagative number on some machines, and the "%"
  442.  * will return a negative number!
  443.  */
  444. symhash(cp)
  445. register char    *cp;
  446. {
  447.     register int    c;
  448.     register int    n;
  449.  
  450.     n = 0;
  451.     while ((c = *cp++) != 0)
  452.         n += c;
  453.     return (n % NSHASH);
  454. }
  455.  
  456. /*
  457.  * Build initial keymap. The funny keys
  458.  * (commands, odd control characters) are mapped using
  459.  * a big table and calls to "keyadd". The printing characters
  460.  * are done with some do-it-yourself handwaving. The terminal
  461.  * specific keymap initialization code is called at the
  462.  * very end to finish up. All errors are fatal.
  463.  */
  464. keymapinit()
  465. {
  466.     register SYMBOL    *sp;
  467.     register KEY    *kp;
  468.     register int    i;
  469.     register int    hash;
  470.  
  471.     for (i=0; i<NKEYS; ++i)
  472.         binding[i] = NULL;
  473.     for (kp = &key[0]; kp < &key[NKEY]; ++kp)
  474.         keyadd(kp->k_key, kp->k_funcp, kp->k_name);
  475.  
  476.     /* Multiple bindings of standard commands */
  477.  
  478. #ifdef DAVEB
  479.         keydup(KCTRL|'Z', "scroll-down");
  480. #endif
  481.     keydup(KCTLX|KCTRL|'G',    "keyboard-quit");
  482.     keydup(KMETA|KCTRL|'G',    "keyboard-quit");
  483.     keydup(KMETA|' ', "set-mark-command");
  484.  
  485.     /*
  486.      * Self insert should be in hash table already, bound to -1.
  487.      * Bind all printing chars without an explicit binding already.
  488.      */
  489.     if ((sp=symlookup("self-insert-command")) == NULL)
  490.         abort();
  491.     binding[ KCTRL|'I' ] = sp;
  492.     for ( i = ' ' ; i < DEL ; ++i ) {
  493.         if (binding[i] != NULL)
  494.             continue;
  495.         binding[i] = sp;
  496.         ++sp->s_nkey;
  497.     }
  498.  
  499.     ttykeymapinit();
  500. }
  501.  
  502. /*
  503.  * Create a new builtin function "name"
  504.  * with function "funcp". If the "new" is a real
  505.  * key, bind it as a side effect. All errors
  506.  * are fatal.
  507.  */
  508. keyadd(new, funcp, name)
  509. int    (*funcp)();
  510. char    *name;
  511. {
  512.     register SYMBOL    *sp;
  513.     register int    hash;
  514.  
  515.     if ((sp=(SYMBOL *)malloc(sizeof(SYMBOL))) == NULL)
  516.         abort();
  517.     hash = symhash(name);
  518.     sp->s_symp = symbol[hash];
  519.     symbol[hash] = sp;
  520.     sp->s_nkey = 0;
  521.     sp->s_name = name;
  522.     sp->s_funcp = funcp;
  523.     if (new >= 0) {                /* Bind this key.    */
  524.         if (binding[new] != NULL)
  525.             abort();
  526.         binding[new] = sp;
  527.         ++sp->s_nkey;
  528.     }
  529. }
  530.  
  531. /*
  532.  * Bind key "new" to the existing routine "name".
  533.  * If the routine doesn't exist, just give a warning.
  534.  * It's no error to rebind a key.
  535.  */
  536. keydup(new, name)
  537. register int    new;
  538. char        *name;
  539. {
  540.     register SYMBOL    *sp;
  541.  
  542.     if ( (sp=symlookup(name))==NULL )
  543.         return;
  544.  
  545.     if( new >= 0 )
  546.         binding[new] = sp;
  547.  
  548.     ++sp->s_nkey;
  549. }
  550.